import { existsSync } from 'node:fs'
import { dirname, join } from 'node:path'
import { mkdir, readFile, writeFile as writeFile_ } from 'node:fs/promises'

import { normalizePath } from 'vite'

export function getDeclaration(ctx: any) {
  const subPagesPath = ctx.subPageMetaData
    .map((sub) => {
      return sub.pages.map((v) => `"/${normalizePath(join(sub.root, v.path))}"`)
    })
    .flat()
  const tabsPagesPath =
    ctx.pagesGlobConfig?.tabBar?.list?.map((v) => {
      return `"/${v!.pagePath}"`
    }) ?? []
  const allPagesPath = [
    ...ctx.pageMetaData
      .filter((page) => !tabsPagesPath.includes(page.path))
      .map((v) => `"/${v.path}"`),
    ...subPagesPath,
  ]
  const code = `/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by vite-plugin-uni-pages

export type NavigateToUrl = ${allPagesPath.join(' |\n       ')};

export interface SwitchTabOptions {
  ${tabsPagesPath.length ? `url: ${tabsPagesPath.join(' | ')}` : ''}
}

`
  return code
}

async function writeFile(filePath: string, content: string) {
  await mkdir(dirname(filePath), { recursive: true })
  return await writeFile_(filePath, content, 'utf-8')
}

export async function writeDeclaration(ctx: any, filepath: string) {
  const originalContent = existsSync(filepath) ? await readFile(filepath, 'utf-8') : ''

  const code = getDeclaration(ctx)
  if (!code) return

  if (code !== originalContent) await writeFile(filepath, code)
}
